#include "OOBB2.h"

void CalculateOOBBCorners(const OOBB2& oobb, Vec2f f[])
{
	f[0] = oobb.centre + (oobb.axis[0] * oobb.extents[0]) + (oobb.axis[1] * oobb.extents[1]);
	f[1] = oobb.centre + (oobb.axis[0] * oobb.extents[0]) + (oobb.axis[1] * oobb.extents[1] * -1);	
	f[2] = oobb.centre + (oobb.axis[0] * oobb.extents[0] * -1) + (oobb.axis[1] * oobb.extents[1]);	
	f[3] = oobb.centre + (oobb.axis[0] * oobb.extents[0] * -1) + (oobb.axis[1] * oobb.extents[1] * -1);		
}

void CalculateOOBBCorners(const OOBB2& oobb, BoxPoints2& bp)
{
	bp.corners[0] = oobb.centre + (oobb.axis[0] * oobb.extents[0]) + (oobb.axis[1] * oobb.extents[1]);
	bp.corners[1] = oobb.centre + (oobb.axis[0] * oobb.extents[0]) + (oobb.axis[1] * oobb.extents[1] * -1);	
	bp.corners[2] = oobb.centre + (oobb.axis[0] * oobb.extents[0] * -1) + (oobb.axis[1] * oobb.extents[1]);	
	bp.corners[3] = oobb.centre + (oobb.axis[0] * oobb.extents[0] * -1) + (oobb.axis[1] * oobb.extents[1] * -1);		
}

float Dot(const Vec2f& v1, const Vec2f& v2)
{
	return float(v1.x * v2.x + v1.y * v2.y);
}

bool CheckCollision(const OOBB2& oobb1, const OOBB2& oobb2)
{
	// get 4 axis
	Vec2f axis[] =
	{
		oobb1.axis[0],
		oobb1.axis[1],
		oobb2.axis[0],
		oobb2.axis[1]
	};

	BoxPoints2 bp1, bp2;

	CalculateOOBBCorners(oobb1, bp1);
	CalculateOOBBCorners(oobb2, bp2);
	
	// for each axis
	float min1, min2, max1, max2;
	for (int i = 0; i != 4; i++)
	{
		float dp1 = Dot(axis[i], bp1.corners[0]);
		min1 = dp1;
		max1 = dp1;
		float dp2 = Dot(axis[i], bp2.corners[0]);
		min2 = dp2;
		max2 = dp2;

		for (int j = 0; j != 4; j++)
		{
			// project box 1
			// get min and max
			float dp1 = Dot(axis[i], bp1.corners[j]);
			if (dp1 < min1)
			{
				min1 = dp1;
			}
			if (dp1 > max1)
			{
				max1 = dp1;
			}
			// same for box 2
			float dp2 = Dot(axis[i], bp2.corners[j]);
			if (dp2 < min2)
			{
				min2 = dp2;
			}
			if (dp2 > max2)
			{
				max2 = dp2;
			}
		}
		// check if they overlap 
		// min1 < max2 && min2 < max1
		if (!(min1 < max2 && min2 < max1))
		{
			return false;
		}
	}
	return true;
}